package com.yanqu.road.dao.impl.activity.fivehero;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.db.DbParameter;
import com.yanqu.road.dao.impl.TempDao;
import com.yanqu.road.entity.activity.fivehero.cross.*;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossFiveHeroDaoImpl extends TempDao {


    public boolean addUserDataList(List<CrossFiveHeroUserData> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "INSERT INTO t_c_activity_fivehero_user_data" +
                "(activityId,userId,unionUid,integral,integralTime,score,tokenTime,campId,hp," +
                "hpTime,serverId,updateTime,eventId,eventCityId,eventCampId,eventTokenId,updatePatronsTime," +
                "luoYangAttTimes,resertTime,redDotMap,addItemMap,tokeScoreMap,groupId,curioAddition)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroUserData data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getUnionUid()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegralTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getScore()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getTokenTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getHp()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getHpTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getServerId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUpdateTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventCampId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventTokenId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUpdatePatronsTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getLuoYangAttTimes()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getResertTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getRedDotMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getAddItemMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getTokeScoreMap())));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getCurioAddition()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateUserDataList(List<CrossFiveHeroUserData> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_fivehero_user_data SET " +
                "unionUid=?,integral=?,integralTime=?,score=?,tokenTime=?,campId=?,hp=?,hpTime=?,serverId=?," +
                "updateTime=?,eventId=?,eventCityId=?,eventCampId=?,eventTokenId=?,updatePatronsTime=?,luoYangAttTimes=?,resertTime=?,redDotMap=?,addItemMap=?,tokeScoreMap=?,curioAddition=?" +
                " WHERE activityId=? and userId = ? and groupId = ?";
        getDb().setConnName(DbNameStrategy.getCross2Db());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroUserData data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.VARCHAR, data.getUnionUid()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegralTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getScore()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getTokenTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getHp()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getHpTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getServerId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUpdateTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventCampId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getEventCampId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUpdatePatronsTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getLuoYangAttTimes()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getResertTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getRedDotMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getAddItemMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getTokeScoreMap())));
            para.put(i++, new DbParameter(Types.BIGINT, data.getCurioAddition()));

            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<Long, CrossFiveHeroUserData> getUserDataMap(int activityId,int groupId) {
        Map<Long,CrossFiveHeroUserData> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_fivehero_user_data WHERE activityId = ? AND groupId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCross2Db());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setInt(i++,groupId);
            rs = call.executeQuery();
            while (rs.next()) {
                CrossFiveHeroUserData data = initUserData(rs);
                dataMap.put(data.getUserId(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private CrossFiveHeroUserData initUserData(ResultSet rs) throws SQLException {
        CrossFiveHeroUserData data = new CrossFiveHeroUserData();
        data.setGroupId(rs.getInt("groupId"));
        data.setActivityId(rs.getInt("activityId"));
        data.setUserId(rs.getLong("userId"));
        data.setUnionUid(rs.getString("unionUid"));
        data.setIntegral(rs.getLong("integral"));
        data.setIntegralTime(rs.getLong("integralTime"));
        data.setScore(rs.getInt("score"));
        data.setTokenTime(rs.getLong("tokenTime"));
        data.setCampId(rs.getInt("campId"));
        data.setHp(rs.getInt("hp"));
        data.setHpTime(rs.getLong("hpTime"));
        data.setServerId(rs.getLong("serverId"));
        data.setUpdateTime(rs.getLong("updateTime"));
        data.setEventId(rs.getInt("eventId"));
        data.setEventCityId(rs.getInt("eventCityId"));
        data.setEventCampId(rs.getInt("eventCampId"));
        data.setEventTokenId(rs.getInt("eventTokenId"));
        data.setUpdatePatronsTime(rs.getLong("updatePatronsTime"));
        data.setLuoYangAttTimes(rs.getInt("luoYangAttTimes"));
        data.setResertTime(rs.getLong("resertTime"));
        data.setCurioAddition(rs.getLong("curioAddition"));
        if(!StringUtils.isNullOrEmpty(rs.getString("redDotMap"))){
            data.setRedDotMap(JSON.parseObject(rs.getString("redDotMap"), new TypeReference<ConcurrentHashMap<Integer, Long>>() {
            }));
        }
        if(!StringUtils.isNullOrEmpty(rs.getString("addItemMap"))){
            data.setAddItemMap(JSON.parseObject(rs.getString("addItemMap"), new TypeReference<ConcurrentHashMap<Integer, Integer>>() {
            }));
        }
        if(!StringUtils.isNullOrEmpty(rs.getString("tokeScoreMap"))){
            data.setTokeScoreMap(JSON.parseObject(rs.getString("tokeScoreMap"), new TypeReference<ConcurrentHashMap<Integer, Long>>() {
            }));
        }
        return data;
    }



    public boolean addPatronsDataList(List<CrossFiveHeroPatrons> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "INSERT INTO t_c_activity_fivehero_patrons_data" +
                "(activityId,userId,id,skin,tokenId,tokenIntegral,ability,addAbilityMap,addPercentageAbilityMap," +
                "nowBlood,type4nowBlood,reviveTimes,type4reviveTimes,lastReviveTime,type4lastReviveTime,lastResetTime,groupId,addPer)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroPatrons data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getSkin()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getTokenId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getTokenIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getAbility()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getAddAbilityMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getAddPercentageAbilityMap())));
            para.put(i++, new DbParameter(Types.BIGINT, data.getNowBlood()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getType4nowBlood()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getReviveTimes()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getType4reviveTimes()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastReviveTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getType4lastReviveTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastResetTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getAddPer()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updatePatronsDataList(List<CrossFiveHeroPatrons> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_fivehero_patrons_data SET " +
                "addPer=?,skin=?,tokenId=?,tokenIntegral=?,ability=?,addAbilityMap=?,addPercentageAbilityMap=?,nowBlood=?,type4nowBlood=?,reviveTimes=?,type4reviveTimes=?,lastReviveTime=?,type4lastReviveTime=?,lastResetTime=?" +
                " WHERE activityId=? and userId = ? and id = ? and groupId = ?";
        getDb().setConnName(DbNameStrategy.getCross2Db());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroPatrons data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getAddPer()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getSkin()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getTokenId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getTokenIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getAbility()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getAddAbilityMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getAddPercentageAbilityMap())));
            para.put(i++, new DbParameter(Types.BIGINT, data.getNowBlood()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getType4nowBlood()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getReviveTimes()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getType4reviveTimes()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastReviveTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getType4lastReviveTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastResetTime()));

            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<Long, Map<Integer,CrossFiveHeroPatrons>> getPatronsDataMap(int activityId,int groupId) {
        Map<Long, Map<Integer,CrossFiveHeroPatrons>> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_fivehero_patrons_data WHERE activityId = ? AND groupId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCross2Db());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setInt(i++,groupId);
            rs = call.executeQuery();
            while (rs.next()) {
                CrossFiveHeroPatrons data = initPatronsData(rs);
                if(!dataMap.containsKey(data.getUserId())){
                    dataMap.put(data.getUserId(),new ConcurrentHashMap<>());
                }
                dataMap.get(data.getUserId()).put(data.getId(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private CrossFiveHeroPatrons initPatronsData(ResultSet rs) throws SQLException {
        CrossFiveHeroPatrons data = new CrossFiveHeroPatrons();
        data.setGroupId(rs.getInt("groupId"));
        data.setActivityId(rs.getInt("activityId"));
        data.setUserId(rs.getLong("userId"));
        data.setId(rs.getInt("id"));
        data.setSkin(rs.getInt("skin"));
        data.setTokenId(rs.getInt("tokenId"));
        data.setTokenIntegral(rs.getInt("tokenIntegral"));
        data.setAbility(rs.getLong("ability"));
        data.setAddAbilityMap(JSON.parseObject(rs.getString("addAbilityMap"), new TypeReference<ConcurrentHashMap<Integer, Long>>() {
        }));
        data.setAddPercentageAbilityMap(JSON.parseObject(rs.getString("addPercentageAbilityMap"), new TypeReference<ConcurrentHashMap<Integer, Long>>() {
        }));
        data.setNowBlood(rs.getLong("nowBlood"));
        data.setType4nowBlood(rs.getLong("type4nowBlood"));
        data.setReviveTimes(rs.getInt("reviveTimes"));
        data.setType4reviveTimes(rs.getInt("type4reviveTimes"));
        data.setLastReviveTime(rs.getLong("lastReviveTime"));
        data.setType4lastReviveTime(rs.getLong("type4lastReviveTime"));
        data.setLastResetTime(rs.getLong("lastResetTime"));
        return data;
    }


    public boolean addBookDataList(List<CrossFiveHeroBookData> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "INSERT INTO t_c_activity_fivehero_book_data" +
                "(activityId,unionUid,campId,no,id,value,getRewardUserIdList,groupId)" +
                " VALUES(?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroBookData data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getUnionUid()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getNo()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getValue()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getGetRewardUserIdList())));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));

            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateBookDataList(List<CrossFiveHeroBookData> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_fivehero_book_data SET " +
                "value=?,getRewardUserIdList=?" +
                " WHERE activityId=? and unionUid = ? and `no` = ? and `groupId` = ?";
        getDb().setConnName(DbNameStrategy.getCross2Db());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroBookData data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getValue()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getGetRewardUserIdList())));

            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getUnionUid()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getNo()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<String, Map<Integer,CrossFiveHeroBookData>> getBookDataMap(int activityId,int groupId) {
        Map<String, Map<Integer,CrossFiveHeroBookData>> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_fivehero_book_data WHERE activityId = ? AND groupId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCross2Db());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setInt(i++,groupId);
            rs = call.executeQuery();
            while (rs.next()) {
                CrossFiveHeroBookData data = initBookData(rs);
                if(!dataMap.containsKey(data.getUnionUid())){
                    dataMap.put(data.getUnionUid(),new ConcurrentHashMap<>());
                }
                dataMap.get(data.getUnionUid()).put(data.getNo(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private CrossFiveHeroBookData initBookData(ResultSet rs) throws SQLException {
        CrossFiveHeroBookData data = new CrossFiveHeroBookData();
        data.setGroupId(rs.getInt("groupId"));
        data.setActivityId(rs.getInt("activityId"));
        data.setUnionUid(rs.getString("unionUid"));
        data.setCampId(rs.getInt("campId"));
        data.setNo(rs.getInt("no"));
        data.setId(rs.getInt("id"));
        data.setValue(rs.getInt("value"));
        data.setGetRewardUserIdList(JSON.parseObject(rs.getString("getRewardUserIdList"), new TypeReference<ArrayList<Long>>() {
        }));
        return data;
    }



    public boolean addCityDataList(List<CrossFiveHeroCity> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "INSERT INTO t_c_activity_fivehero_city_data" +
                "(activityId,cityId,campId,occupyTime,defPatronsMap,diePatronsList," +
                "defTokenMap,occUserId,lastRecoveryExtraTeamTime,expAddTime,banditMap,groupId,killCountMap)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroCity data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOccupyTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDefPatronsMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDiePatronsList())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDefTokenMap())));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOccUserId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastRecoveryExtraTeamTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getExpAddTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getBanditMap())));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getKillCountMap())));


            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateCityDataListNoPatrons(List<CrossFiveHeroCity> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_fivehero_city_data SET " +
                "campId=?,occupyTime=?,defTokenMap=?," +
                "occUserId=?,lastRecoveryExtraTeamTime=?,expAddTime=?,banditMap=?,killCountMap=?" +
                " WHERE activityId=? and cityId = ? and groupId = ?";
        getDb().setConnName(DbNameStrategy.getCross2Db());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroCity data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOccupyTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDefTokenMap())));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOccUserId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastRecoveryExtraTeamTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getExpAddTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getBanditMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getKillCountMap())));

            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateCityDataList(List<CrossFiveHeroCity> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_fivehero_city_data SET " +
                "campId=?,occupyTime=?,defPatronsMap=?,diePatronsList=?,defTokenMap=?," +
                "occUserId=?,lastRecoveryExtraTeamTime=?,expAddTime=?,banditMap=?,killCountMap=?" +
                " WHERE activityId=? and cityId = ? and groupId = ?";
        getDb().setConnName(DbNameStrategy.getCross2Db());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroCity data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOccupyTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDefPatronsMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDiePatronsList())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getDefTokenMap())));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOccUserId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastRecoveryExtraTeamTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getExpAddTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getBanditMap())));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getKillCountMap())));

            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<Integer,CrossFiveHeroCity> getCityDataMap(int activityId,int groupId) {
        Map<Integer,CrossFiveHeroCity> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_fivehero_city_data WHERE activityId = ? AND groupId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCross2Db());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setInt(i++,groupId);
            rs = call.executeQuery();
            while (rs.next()) {
                CrossFiveHeroCity data = initCityData(rs);
                dataMap.put(data.getCityId(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private CrossFiveHeroCity initCityData(ResultSet rs) throws SQLException {
        CrossFiveHeroCity data = new CrossFiveHeroCity();
        data.setGroupId(rs.getInt("groupId"));
        data.setActivityId(rs.getInt("activityId"));
        data.setCityId(rs.getInt("cityId"));
        data.setCampId(rs.getInt("campId"));
        data.setOccupyTime(rs.getLong("occupyTime"));
        data.setDefPatronsMap(JSON.parseObject(rs.getString("defPatronsMap"), new TypeReference<ConcurrentHashMap<Integer, CrossFiveHeroBattlePatrons>>() {
        }));
        data.setDiePatronsList(JSON.parseObject(rs.getString("diePatronsList"), new TypeReference<LinkedList<CrossFiveHeroBattlePatrons>>() {
        }));
        data.setDefTokenMap(JSON.parseObject(rs.getString("defTokenMap"), new TypeReference<ConcurrentHashMap<Integer, CrossFiveHeroToken>>() {
        }));
        data.setOccUserId(rs.getLong("occUserId"));
        data.setLastRecoveryExtraTeamTime(rs.getLong("lastRecoveryExtraTeamTime"));
        data.setExpAddTime(rs.getLong("expAddTime"));
        data.setBanditMap(JSON.parseObject(rs.getString("banditMap"), new TypeReference<ConcurrentHashMap<Integer, CrossFiveHeroBandit>>() {
        }));
        if(!StringUtils.isNullOrEmpty(rs.getString("killCountMap"))){
            data.setKillCountMap(JSON.parseObject(rs.getString("killCountMap"), new TypeReference<ConcurrentHashMap<Long, Integer>>() {
            }));
        }

        return data;
    }


    public Map<Long,List<CrossFiveHeroUserReport>> getUserReportDataMap(int activityId,int limitCount,int groupId) {
        Map<Long,List<CrossFiveHeroUserReport>> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        //取这么多战报，后面的不管了
        String sql = "SELECT * FROM t_c_activity_fivehero_user_report WHERE activityId = ? AND groupId = ? " +
                "ORDER BY `time` DESC " +
                "LIMIT 5000 ";
        try {
            getDb().setConnName(DbNameStrategy.getCross2Db());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setInt(i++,groupId);
            rs = call.executeQuery();
            while (rs.next()) {
                CrossFiveHeroUserReport data = initUserReportData(rs);
                if(!dataMap.containsKey(data.getUserId())){
                    dataMap.put(data.getUserId(),new ArrayList<>());
                }
                if(dataMap.get(data.getUserId()).size() >= limitCount){
                    continue;
                }
                dataMap.get(data.getUserId()).add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private CrossFiveHeroUserReport initUserReportData(ResultSet rs) throws SQLException {
        CrossFiveHeroUserReport data = new CrossFiveHeroUserReport();
        data.setGroupId(rs.getInt("groupId"));
        data.setActivityId(rs.getInt("activityId"));
        data.setUserId(rs.getLong("userId"));
        data.setCityId(rs.getInt("cityId"));
        data.setBattleCount(rs.getInt("battleCount"));
        data.setRobReward(rs.getString("robReward"));
        data.setAttReward(rs.getString("attReward"));
        data.setTime(rs.getLong("time"));
        data.setNickName(rs.getString("nickName"));
        data.setCampId(rs.getInt("campId"));
        return data;
    }

    public boolean addUserReportDataList(List<CrossFiveHeroUserReport> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "INSERT INTO t_c_activity_fivehero_user_report" +
                "(activityId,userId,cityId,battleCount,robReward,attReward,time,nickName,campId,groupId)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroUserReport data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getBattleCount()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getRobReward()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getAttReward()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getTime()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getNickName()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public List<CrossFiveHeroCityReport> getCityReportDataMap(int activityId,int limitCount,int groupId,int cityId,boolean isLuoYang) {
        List<CrossFiveHeroCityReport> dataList = new ArrayList<>();
        ResultSet rs = null;
        CallableStatement call = null;
        //取这么多战报，后面的不管了
        String sql = "";
        if(!isLuoYang){
            sql = "SELECT * FROM t_c_activity_fivehero_city_report WHERE activityId = ? AND groupId = ? AND cityId != " + cityId +
                    " ORDER BY `time` DESC " +
                    " LIMIT " + limitCount;
        }else{
            sql = "SELECT * FROM t_c_activity_fivehero_city_report WHERE activityId = ? AND groupId = ? AND cityId = " + cityId +
                    " ORDER BY `time` DESC " +
                    " LIMIT " + limitCount;
        }
        try {
            getDb().setConnName(DbNameStrategy.getCross2Db());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setInt(i++,groupId);
            rs = call.executeQuery();
            while (rs.next()) {
                CrossFiveHeroCityReport data = initCityReportData(rs);
                dataList.add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataList;
    }

    private CrossFiveHeroCityReport initCityReportData(ResultSet rs) throws SQLException {
        CrossFiveHeroCityReport data = new CrossFiveHeroCityReport();
        data.setGroupId(rs.getInt("groupId"));
        data.setActivityId(rs.getInt("activityId"));
        data.setCityId(rs.getInt("cityId"));
        data.setBattleCount(rs.getInt("battleCount"));
        data.setIsRob(rs.getInt("isRob"));
        data.setCampId(rs.getInt("campId"));
        data.setUserId(rs.getLong("userId"));
        data.setNickName(rs.getString("nickName"));
        data.setDecoration(rs.getString("decoration"));
        data.setDefCampId(rs.getInt("defCampId"));
        data.setTime(rs.getLong("time"));
        data.setBeAttTokenNickName(rs.getString("beAttTokenNickName"));
        return data;
    }

    public boolean addCityReportDataList(List<CrossFiveHeroCityReport> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "INSERT INTO t_c_activity_fivehero_city_report" +
                "(activityId,cityId,battleCount,isRob,campId,userId,nickName,decoration,defCampId,time,groupId,beAttTokenNickName)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroCityReport data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getBattleCount()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getIsRob()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getCampId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getNickName()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getDecoration()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getDefCampId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getBeAttTokenNickName()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean addRankDataList(List<CrossFiveHeroRank> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCross2Db());
        String sql = "REPLACE INTO t_c_activity_fivehero_rank" +
                "(`activityId`,`rankType`,`id`,`value`,`time`,`ability`,`popularity`,`rank`,`groupId`)" +
                " VALUES(?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CrossFiveHeroRank data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getRankType()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getValue()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getAbility()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getPopularity()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getRank()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getGroupId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }



}
